package YAVMM::Server::REST;
use warnings;
use strict;

use Dancer ':syntax';
set serializer => 'JSON';

use Template;

use YAVMM::Server::Utils;
use YAVMM::Server::Auth;

use YAVMM::HostStatDB;
use YAVMM::HostStat;

use TryCatch;
use DateTime;

our $VERSION = '0.1';

#get '/json/:id/' => sub {
#    return { foo => params->{foo}, #"Bar",
#	     baz => [10, 14, 32, 2, 6, { good => "bye" }],
#	     id  => params->{id},
#	 };
#};

get '/json/clusters' => sub {
    try {
	my $hostdb = YAVMM::Server::Utils::get_hostdb();
	return [ $hostdb->get_clusters() ];
    } catch {
    }
};

# Decode the returned list like so:
# @objs = map { YAVMM::Host->unpack($_) } @{ decode_json($json) };
# @objs now is a list of YAVMM::Host objects
get '/json/hosts' => sub {
    my $hostdb = YAVMM::Server::Utils::get_hostdb();

    try {
	if (params->{cluster}) {
	    return [ $hostdb->get_hosts(params->cluster) ];
	}
	else {
	    return [ $hostdb->get_hosts() ];
	}
    } catch (YAVMM::Error $err) {
	error $err;
	return ($err->error, 500);
    }
};

get '/json/host/:name' => sub {
    try {
#	return YAVMM::Server::Utils::get_hostdb->get_host(params->{name})->freeze;
	return YAVMM::Server::Utils::get_hostdb->get_host(params->{name});
    } catch {
	error $_;
	# set error code, etc.
	status 500;
	return { status => "Unable to get host (".params->{name}."): $_" };

    }
};

get '/json/update_stats' => sub {
    my $now = DateTime->now(time_zone => 'UTC')->epoch;
    # ps aexo pcpu,pmem,vsz,rss,cmd
    my $ps;
    if (not open ($ps, '-|', "ps haexo pcpu,pmem,vsz,rss,cmd")) {
	debug 'update_stats: open failed';
	status 500;
	return { status => "Unable to get process list: $!" };
    }

    debug 'update_stats: open succeeded';

    my $pmem_used = 0;
    my $vsz_used  = 0;
    my $rss_used  = 0;
    my $cpu_used  = 0;

    foreach my $line (<$ps>) {
	chomp $line;
	my ($pcpu, $pmem, $vsz, $rss, $cmd) = split ' ', $line;
	$cpu_used  += $pcpu;
	$pmem_used += $pmem;
	$vsz_used  += $vsz;
	$rss_used  += $rss;

	# TODO: abstract this regex out
	if ($cmd =~ m|qemu\S+\s|x) {
	    # build guest stat
	    # parse command line. Should be done by the GuestManager
	    my $guest = YAVMM::Server::Utils::get_guest_manager();
	    my $guest_stat = YAVMM::GuestStat->new(
		name      => $guest->name,
		timestamp => $now,
		host_name => vars->{name},
		vsz       => $vsz,
		rss       => $rss,
		cpu_used  => $pcpu,
		mem_used  => $pmem,
	    );
	}
    }

    close $ps;

    try {
	my $stat = YAVMM::HostStat->new(
	    name      => vars->{name},
	    timestamp => $now,
	    cpu_used  => $cpu_used / YAVMM::Server::Utils::get_host(vars->{name})->num_cpus,
	    pmem_used => $pmem_used,
	    vsz_used  => $vsz_used,
	    rss_used  => $rss_used,
	);

	debug 'adding stat to hoststatdb';

	YAVMM::Server::Utils::get_hoststatdb->add_stat($stat);
	return { status => "Success"};
    } catch (YAVMM::Error $err) {
	status 500;
	return { status => "Unable to update host stats: $err" };
    }
};

#put '/json/login' => sub {
put '/login' => sub {
    my $login_successful = 0;
    my $user = params->{user};
    my $pass = params->{pass};

    my $auth = YAVMM::Server::Auth->new(settings => vars->{settings});
    $auth->load_plugin(config->{'auth plugin'});

    $login_successful = $auth->authenticate($user, $pass);

    if ($login_successful) {
	session user => $user;
	return { status => 'Login successful' };
    }
    else {
	status 403;
	return { status => 'Bad user name or password' };
    }
};

put '/logout' => sub {
    session user => undef;
    session->destroy;
    return { status => "Logged out" };
};

1;

__END__
